package com.schoolvisitors.service;


import com.alibaba.fastjson2.JSONArray;
import com.schoolvisitors.dto.AddResourcePermissionDto;
import com.schoolvisitors.dto.RoleDto;
import com.schoolvisitors.entity.RoleResource;
import com.schoolvisitors.entity.Role;
import com.schoolvisitors.exception.BusinessException;
import com.schoolvisitors.repository.AdminRepository;
import com.schoolvisitors.repository.ResourcesRepository;
import com.schoolvisitors.repository.RoleRepository;
import com.schoolvisitors.response.ResultBody;
import com.schoolvisitors.response.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
public class RoleService {

    private final RoleRepository roleRepository;
    private final ResourcesRepository resourcesRepository;
    private final AdminRepository adminRepository;

    @Autowired
    public RoleService(RoleRepository roleRepository, ResourcesRepository resourcesRepository, AdminRepository adminRepository) {
        this.roleRepository = roleRepository;
        this.resourcesRepository = resourcesRepository;
        this.adminRepository = adminRepository;
    }

    // 获取角色列表
    public List<RoleDto> getRoles() {
        List<RoleDto> roles = new ArrayList<>();
        for (Role role : roleRepository.findAllByDeleteFalse()) {
            RoleDto roleDto = new RoleDto();
            roleDto.setId(role.getId());
            roleDto.setName(role.getName());
            roleDto.setPermissions(JSONArray.parseArray(role.getPermissions()));
            roles.add(roleDto);
        }
        return roles;
    }

    // 添加角色
    public ResultBody addRole(Role role) {
        if (role.getPermissions().isEmpty()){
            role.setPermissions("[]");
        }
        Role createdRole = roleRepository.save(role);
        return ResultBody.success(createdRole);
    }

    public Role getRoleById(Long id){
        return roleRepository.findById(id).orElse(null);
    }

    public void deleteRole(Long roleId) {
        Role role = roleRepository.findById(roleId).orElseThrow(() -> new BusinessException(ResultCode.ROLE_NOT_FOUND));
        if (adminRepository.existsAdminByRoleAndDeleteFalse(role)){
            throw new BusinessException(ResultCode.ADMIN_HAS_ROLE);
        }
        role.setDelete(true);
        roleRepository.save(role);
    }

    public void updateRole(Role role) {
        roleRepository.save(role);
    }

    public List<RoleResource> getRoleResources(Long roleId) {
        return resourcesRepository.findByRoleId(roleId);

    }
    public void deleteRoleResource(Long resourceId) {
        resourcesRepository.deleteById(resourceId);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addResourcePermission(AddResourcePermissionDto dto) {
        Role role = getRoleById(dto.getRoleId());
        if (role == null) {
            throw new BusinessException(ResultCode.ROLE_NOT_FOUND);
        }
        if (null != resourcesRepository.findByRoleIdAndTypeAndResourceIndex(role.getId(), dto.getType(), dto.getResourceIndex())){
            throw new BusinessException(ResultCode.ROLE_HAS_RESOURCE);
        }

        RoleResource resource = new RoleResource();
        resource.setRoleId(role.getId());
        resource.setType(dto.getType());
        resource.setResourceIndex(dto.getResourceIndex());
        resourcesRepository.save(resource);
    }
}
